#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<unistd.h>
#include<pthread.h>

using namespace std;

// #define NUM 4

// class threadData{
// public:
//     threadData(int number){
//         threadname = "thread-"+to_string(number);
//     }
// public:
//     string threadname;
// };

// int tickets = 1000;

// void *getTiket(void *args){
//     threadData *td = static_cast<threadData *>(args);
//     const char *name = td->threadname.c_str();
//     while(true){
//         if(tickets > 0){//并发会抢到错误的ticket
//             usleep(1000);
//             printf("who:%s, get a ticket: %d\n",name,tickets);
//             tickets--;
//         }else
//             break;
//         printf("%s ... quit\n",name);
//     }
//      return nullptr;
// }

// int main(){
//     vector<pthread_t> tids;
//     vector<threadData *> thread_datas;
//     for(int i=1;i<=NUM;i++){
//         pthread_t tid;
//         threadData *td = new threadData(i);
//         thread_datas.push_back(td);
//         pthread_create(&tid,nullptr,getTiket,thread_datas[i-1]);
//         tids.push_back(tid);
//     }

//     for(auto thread : tids){
//         pthread_join(thread,nullptr);
//     }
    
//     for(auto td:thread_datas){
//         delete td;
//     }
//     return 0;
// }


// part2:

#define NUM 3

int *p = NULL;

int test_i_1 = 0;
__thread int g_val = 100;
__thread unsigned int number = 0;
__thread int pid = 0;

struct threadData{
    string threadname;
};

// __thread threadData td;

string toHex(pthread_t tid){//传入数据，内存中的内容转十六进制,再转字符串
    char buffer[128];
    snprintf(buffer, sizeof(buffer),"0x%x",tid);
    return buffer;
}

void InitThreadData(threadData *td, int number){
    td->threadname = "thread-" + to_string(number);
}

void *threadRoutine(void *args){
    pthread_detach(pthread_self());
    
    int test_i = 0;
    test_i_1++;
    threadData *td = static_cast<threadData *>(args);
     if(td->threadname == "thread-2") p = &test_i_1;
    string tid = toHex(pthread_self());
    int pid = getpid();
    
    int i=0;
    while(i<10){
        cout<<"tid: "<<tid<<", pid: "<<pid<<endl;
        
        cout<<"pid: "<<getpid()<<",num: "
            <<toHex(number)<<", threadname: "<<td->threadname
            <<", g_val: "<<g_val<<" ,&g_val: "<<&g_val<<endl;
        sleep(1);
        i++;
    }

    delete td;
    return nullptr;
}

int main(){
    // 创建多线程
    vector<pthread_t> tids; 
    vector<threadData *> thread_datas;
    for(int i=0;i<NUM;i++){
        pthread_t tid;//线程结构体
        threadData *td = new threadData;
        InitThreadData(td,i);
        
        pthread_create(&tid,nullptr,threadRoutine,td);//线程creat
        tids.push_back(tid);//vector加载信息
        sleep(1);
    }
    
    for(auto i  : tids){
        pthread_detach(i);//分离线程
    }
    cout << "main thread get a thread local value, val: " << *p << ", &val: " << p << endl;//主线程
    
    for(int i=0;i<tids.size();i++){
        int n = pthread_join(tids[i],nullptr);//阻塞等待线程结束
        printf("n = %d, who = 0x%x, why: %s\n",n,tids[i],strerror(n));
    }
    return 0;
}